package com.controller;

import com.beans.DeviceEntity;
import com.beans.FileDepotEntity;
import com.beans.RadioDepotEntity;
import org.dom4j.Document;
import org.dom4j.DocumentHelper;
import org.dom4j.Element;
import org.dom4j.io.OutputFormat;
import org.dom4j.io.XMLWriter;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

public class XmlDo4j {

    public static void main(String[] args) {
        List<RadioDepotEntity> list = new ArrayList<>();
        new XmlDo4j().createRadioDocument(list);
    }

    /**
     * 选择题
     * @param list
     * @return
     */
    public byte[] createRadioDocument(List<RadioDepotEntity> list) {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("Documents");
        root.addComment("title：题目；optionA：A选项；optionB：B选项；optionC：C选项；optionD：D选项；answer：答案（0为A，1为B，2为C，3为D）");

        for (RadioDepotEntity radioDepotEntity : list) {
            String answer = "4";
            if(radioDepotEntity.getAnswer().equalsIgnoreCase("A")){
                answer = "0";
            }
            if(radioDepotEntity.getAnswer().equalsIgnoreCase("B")){
                answer = "1";
            }
            if(radioDepotEntity.getAnswer().equalsIgnoreCase("C")){
                answer = "2";
            }
            if(radioDepotEntity.getAnswer().equalsIgnoreCase("D")){
                answer = "3";
            }
            Element radio = root.addElement("radio")
                    .addAttribute("id",radioDepotEntity.getId()+"")
                    .addAttribute("title",radioDepotEntity.getTitle())
                    .addAttribute("optionA",radioDepotEntity.getOptionA())
                    .addAttribute("optionB",radioDepotEntity.getOptionB())
                    .addAttribute("optionC",radioDepotEntity.getOptionC())
                    .addAttribute("optionD",radioDepotEntity.getOptionD())
                    .addAttribute("answer",answer);
        }

        return write(document);
    }

    /**
     * 操作题
     * @param list
     * @return
     */
    public byte[] createFileDocument(List<FileDepotEntity> list) {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("Documents");
        root.addComment("titleType：题的类型；fileName：题的名称，根据名称在同一包下找相应的压缩文件");
        for (FileDepotEntity fileDepotEntity : list) {
            root.addElement("file")
                    .addAttribute("id",fileDepotEntity.getId()+"")
                   // .addAttribute("summary",fileDepotEntity.getSummary())
                    .addAttribute("titleType",fileDepotEntity.getTitleType())
                   // .addAttribute("fileSize",fileDepotEntity.getFileSize())
                    .addAttribute("fileName",fileDepotEntity.getFileName());
        }

        return write(document);
    }

    /**
     * 考员信息
     * @param list
     * @return
     */
    public byte[] createStudentDocument(List<DeviceEntity> list) {
        Document document = DocumentHelper.createDocument();
        Element root = document.addElement("testees");
        root.addComment("id：学号；name：考生姓名");
        for (DeviceEntity deviceEntity : list) {
            root.addElement("testee")
                    .addAttribute("id",deviceEntity.getId()+"")
                    .addAttribute("name",deviceEntity.getBrands());
        }

        return write(document);
    }

    public byte[] write(Document document) {
        try(ByteArrayOutputStream os = new ByteArrayOutputStream()){
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("UTF-8");
            format.setNewlines(true);
            format.setIndent(true);
            XMLWriter writer = new XMLWriter(os,format);
            writer.write( document );

            writer.close();
            return os.toByteArray();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    public byte[] write(Document document,String fileName) {
        try(FileWriter fileWriter = new FileWriter(fileName)){
            OutputFormat format = OutputFormat.createPrettyPrint();
            format.setEncoding("UTF-8");
            format.setNewlines(true);
            format.setIndent(true);
            XMLWriter writer = new XMLWriter(fileWriter,format);
            writer.write( document );
            writer.close();
            fileWriter.close();
            return getBytes(fileName);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 压缩成ZIP 方法2
     * @param srcFiles 需要压缩的文件列表
     * @param out           压缩文件输出流
     * @throws RuntimeException 压缩失败会抛出运行时异常
     */

    public static void toZip(List<File> srcFiles , OutputStream out)throws RuntimeException {
        long start = System.currentTimeMillis();
        ZipOutputStream zos = null ;
        try {
            zos = new ZipOutputStream(out);
            for (File srcFile : srcFiles) {
                byte[] buf = new byte[1024];
                zos.putNextEntry(new ZipEntry(srcFile.getName()));
                int len;
                FileInputStream in = new FileInputStream(srcFile);
                while ((len = in.read(buf)) != -1){
                    zos.write(buf, 0, len);
                }
                zos.closeEntry();
                in.close();
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) +" ms");
        } catch (Exception e) {
            throw new RuntimeException("zip error from ZipUtils",e);
        }finally{
            if(zos != null){
                try {
                    zos.close();
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 压缩zip
     * 指定下载文件的文件名 response.setHeader("Content-Disposition", "attachment;filename=xxx.txt");
     *
     * @param srcFiles 压缩文件源 key：文件名 value：文件内容
     * @param out 输出流
     */
    public static void toZip(Map<String, byte[]> srcFiles, OutputStream out) {
        long start = System.currentTimeMillis();
        try (ZipOutputStream zos = new ZipOutputStream(out)) {
            for (Map.Entry<String, byte[]> srcFile : srcFiles.entrySet()) {
                zos.putNextEntry(new ZipEntry(srcFile.getKey()));
                zos.write(srcFile.getValue());
                zos.closeEntry();
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) + " ms");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 压缩zip
     * 指定下载文件的文件名 response.setHeader("Content-Disposition", "attachment;filename=xxx.txt");
     *
     * @param srcFiles 压缩文件源 key：文件名 value：文件内容
     * @param out 输出流
     */
    public static void toZip2(List<FileDepotEntity> srcFiles, OutputStream out) {
        long start = System.currentTimeMillis();
        try (ZipOutputStream zos = new ZipOutputStream(out)) {
            for (FileDepotEntity fileDepotEntity : srcFiles) {
                zos.putNextEntry(new ZipEntry(fileDepotEntity.getFileName()));
                zos.write(fileDepotEntity.getFileZip());
                zos.closeEntry();
            }
            long end = System.currentTimeMillis();
            System.out.println("压缩完成，耗时：" + (end - start) + " ms");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    //获得指定文件的byte数组
    public static byte[] getBytes(String filePath){
        byte[] buffer = null;
        try {
            File file = new File(filePath);
            FileInputStream fis = new FileInputStream(file);
            ByteArrayOutputStream bos = new ByteArrayOutputStream(1024);
            byte[] b = new byte[1024];
            int n;
            while ((n = fis.read(b)) != -1) {
                bos.write(b, 0, n);
            }
            fis.close();
            bos.close();
            buffer = bos.toByteArray();
        } catch (FileNotFoundException e) {
            e.printStackTrace();
        } catch (IOException e) {
            e.printStackTrace();
        }
        return buffer;
    }

}
